#include "squarewaveview.h"
#include "ui_squarewaveview.h"

SquareWaveView::SquareWaveView(QWidget *parent) :
    BaseView(parent),
    ui(new Ui::SquareWaveView)
{
    ui->setupUi(this);

//    setPalette(QPalette(Qt::gray)); // 设置窗口为白色背景
//    setAutoFillBackground(true);
    resize(600,400);
    init();
}

QLineSeries* SquareWaveView::createSeries(const std::vector<std::pair<float,float>>& dataPoints)
{
    // 创建曲线
    QLineSeries* series = new QLineSeries(m_chart);
    series->setPointLabelsFormat("(@xPoint,@yPoint)");
    series->setPointLabelsVisible(true);
    series->setPointsVisible(true);
    if(ui->seriesNameEdit->text()!=""){
        series->setName(ui->seriesNameEdit->text());
    }
    // 要设置折线颜色，否则看不到
    QPen pen;
    pen.setWidth(3);
    pen.setColor(Qt::blue);
    pen.setStyle(Qt::DotLine);
    series->setPen(pen);
    // 添加数据点
    series->clear(); // remove all points from series
    for(auto point:dataPoints){
        series->append(point.first,point.second);
        qDebug() << point.first<<" "<<point.second;
    }
    return series;
}

QLineSeries* SquareWaveView::createGridSeries(float minX, float maxX)
{
    // 设置额定值曲线
    QLineSeries* gridSeries = new QLineSeries(m_chart);
    gridSeries = new QLineSeries(this);
    gridSeries->setName("额定值曲线");
    gridSeries->setPointLabelsVisible(true);
    gridSeries->setPointLabelsFormat("@yPoint");
    QPen pen;
    pen.setColor(Qt::red);
    pen.setStyle(Qt::SolidLine);
    pen.setWidth(3);
    gridSeries->setPen(pen);
    QString gridStrVal = ui->gridValEdit->text();
    bool ok;
    float gridVal = gridStrVal.toFloat(&ok);
    gridSeries->clear();
    if(ok){
        // 额定值曲线的x轴为 0-100
        gridSeries->append(QPointF(0,gridVal));
        gridSeries->append(QPointF(100,gridVal));
        m_gridVal = gridVal;
    }
    return gridSeries;
}

void SquareWaveView::init()
{
    QScreen* screen = QGuiApplication::primaryScreen();
    ui->leftWidget->setFixedWidth(screen->availableGeometry().width()/4);
    m_chart = new QChart;
    ui->chartView->setChart(m_chart);

    // 点击工具栏按钮实现隐藏/显示
    connect(ui->setDataWidget,&QPushButton::clicked,this,&SquareWaveView::onSetDataBtnClicked);
    connect(ui->setSeriesWidget,&QPushButton::clicked,this,&SquareWaveView::onSetSeriesBtnClicked);
    connect(ui->setAxisWidget,&QPushButton::clicked,this,&SquareWaveView::onSetAxisBtnClicked);

    // 第一个工具栏
    // 创建曲线
    connect(ui->createSeriesBtn,&QPushButton::clicked,this,&SquareWaveView::onCreateSeriesBtnClicked);
    // 删除当前曲线
    connect(ui->delSeriesBtn,&QPushButton::clicked,this,&SquareWaveView::onDelSeriesBtnClicked);

    // 第二个工具栏
    // 设置曲线颜色
    connect(ui->setSeriesColorBtn,&QPushButton::clicked,this,&SquareWaveView::onSetSeriesColorBtnClicked);
    // 是否显示数据点
    connect(ui->isDataPointShow,&QCheckBox::clicked,this,&SquareWaveView::onIsDataPointShowChecked);
    // 设置数据点标签颜色
    connect(ui->setDataPointLabColorBtn,&QPushButton::clicked,this,&SquareWaveView::onSetDataPointLabColorBtnClicked);
    // 设置数据点标签字体
    connect(ui->setDataPointLabFontBtn,&QPushButton::clicked,this,&SquareWaveView::onSetDataPointLabFontBtnClicked);
    // 设置图例是否可见
    connect(ui->isLegendVisible,&QCheckBox::clicked,this,&SquareWaveView::onIsLegendVisibleChecked);
    // 设置数据点标签格式
    connect(ui->xyPointBtn,&QRadioButton::clicked,this,&SquareWaveView::onxyPointBtnChecked);
    connect(ui->yPointBtn,&QRadioButton::clicked,this,&SquareWaveView::onyPointBtnChecked);

    // 第三个工具栏
    // 点击x、y轴选择的radiobutton
    connect(ui->xAxisBtn,&QRadioButton::clicked,this,&SquareWaveView::onAxisBtnClicked);
    connect(ui->yAxisBtn,&QRadioButton::clicked,this,&SquareWaveView::onAxisBtnClicked);
    // 设置坐标轴的主刻度线、次刻度线颜色
    connect(ui->setTickColorBtn,&QPushButton::clicked,this,&SquareWaveView::onSetTickColorBtnClicked);
    connect(ui->setMinorTickColorBtn,&QPushButton::clicked,this,&SquareWaveView::onSetMinorTickColorBtnClicked);
    // 设置坐标轴名称
    connect(ui->setAxisNameBtn,&QPushButton::clicked,this,&SquareWaveView::onSetAxisNameBtnClicked);
    // 设置坐标轴上下限
    auto signalValueChanged = static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged);
    connect(ui->axisUpSpinBox,signalValueChanged,this,&SquareWaveView::onAxisUpSpinBoxChanged);
    connect(ui->axisDownSpinBox,signalValueChanged,this,&SquareWaveView::onAxisDownSpinBoxChanged);
    // 设置坐标轴的主、次刻度线
    connect(ui->setTickSpinBox,signalValueChanged,this,&SquareWaveView::onSetTickSpinBoxChanged);
    connect(ui->setMinorTickSpinBox,signalValueChanged,this,&SquareWaveView::onSetMinorTickSpinBoxChanged);
}

SquareWaveView::~SquareWaveView()
{
    delete ui;
}

std::vector<float> SquareWaveView::splitStr2Vec(const QString &str)
{
    std::vector<float> res;
    QVector<QString> strList = str.split(",").toVector();
    for(int i=0;i<strList.size();++i){
        bool ok;
        float num = strList.at(i).toFloat(&ok);
        if(!ok){
            QMessageBox::warning(this,"创建序列","输入的数组有误！");
            return {};
        }
        res.push_back(num);
    }
    return res;
}

void SquareWaveView::onSetDataBtnClicked()
{
    if(ui->dataSetScrollArea->isHidden()){
        ui->dataSetScrollArea->show();
    }else{
        ui->dataSetScrollArea->hide();
    }
}

void SquareWaveView::onSetAxisBtnClicked()
{
    if(ui->axisSetScrollArea->isHidden()){
        ui->axisSetScrollArea->show();
    }else{
        ui->axisSetScrollArea->hide();
    }
}

void SquareWaveView::onSetSeriesBtnClicked()
{
    if(ui->seriesSetScrollArea->isHidden()){
        ui->seriesSetScrollArea->show();
    }else{
        ui->seriesSetScrollArea->hide();
    }
}

QValueAxis *SquareWaveView::createAxis(float min, float max)
{
    QValueAxis* axis = new QValueAxis(m_chart);
    axis->setRange(min-1,max+1);
    axis->setTickCount(10);
    axis->setMinorTickCount(4);
    return axis;
}

std::vector<std::pair<float, float> > SquareWaveView::getDataPoints(const std::vector<float> &xData, const std::vector<float> &yData)
{
        if (xData.size() != yData.size()) {
            qDebug() << "error!";
            return {};
        }
        float curTime = 0;
        std::vector<std::pair<float, float>> res;
        // AC源输出前额定电压输出5s
        if (m_gridVal != 0) {
            res.push_back({ curTime,m_gridVal });
            curTime += 5;
            res.push_back({ curTime,m_gridVal });
        }
        int n = xData.size();
        for (int i = 0; i < n; ++i) {
            res.push_back({curTime,yData[i]});
            curTime += xData[i];
            res.push_back({ curTime,yData[i] });
        }
        // AC源输出后额定电压输出5s
        if (m_gridVal != 0) {
            res.push_back({ curTime,m_gridVal });
            curTime += 5;
            res.push_back({ curTime,m_gridVal });
        }
        return res;
 }

void SquareWaveView::onCreateSeriesBtnClicked()
{
    // 处理x、y的数据
    // 将x、y点的数据转换成数组
    QString xStrData = ui->xDataEdit->toPlainText();
    std::vector<float> xData = splitStr2Vec(xStrData);
    if(xData.size()<=0)return;
    QString yStrData = ui->yDataEdit->toPlainText();
    std::vector<float> yData = splitStr2Vec(yStrData);
    if(yData.size()<=0)return;
    if(xData.size()!=yData.size()){
        QMessageBox::warning(this,"创建序列","输入的x、y值数量不同或为空");
        return;
    }
    // 获取x、y轴的最小值与最大值
    float minX = xData[0],maxX = xData[0];
    float minY = yData[0],maxY = yData[0];
    for(size_t i=0;i<xData.size();++i){
        minX = std::min(minX,xData[i]);
        maxX = std::max(maxX,xData[i]);
        minY = std::min(minY,yData[i]);
        maxY = std::max(maxY,yData[i]);
    }

    // 创建xy数据曲线、额定值曲线
    if(m_gridSeries == nullptr){
        m_gridSeries = createGridSeries(minX,maxX);
        m_chart->addSeries(m_gridSeries);
    }
    auto dataPoints = getDataPoints(xData,yData);
    if(m_series == nullptr){
        m_series = createSeries(dataPoints);
        m_chart->addSeries(m_series);
    }

    // 创建、设置坐标轴
    QValueAxis* xAxis = dynamic_cast<QValueAxis*>((m_chart->axisX(m_series)));
    if(xAxis==nullptr){
        xAxis = createAxis(0,100);
        m_chart->setAxisX(xAxis,m_series);
        if(m_gridSeries!=nullptr){
            m_chart->setAxisX(xAxis,m_gridSeries);
        }
    }
    QValueAxis* yAxis = dynamic_cast<QValueAxis*>((m_chart->axisY(m_series)));
    if(yAxis==nullptr){
        yAxis = createAxis(minY,maxY);
        m_chart->setAxisY(yAxis,m_series);
        if(m_gridSeries!=nullptr){
            m_chart->setAxisY(yAxis,m_gridSeries);
        }
    }
    m_chart->update();
}

void SquareWaveView::onSetSeriesColorBtnClicked()
{
    if(m_series==nullptr)return;
    QColor seriesColor = m_series->color();
    QColor color = QColorDialog::getColor(seriesColor);
    m_series->setColor(color);
}

void SquareWaveView::onDelSeriesBtnClicked()
{
    // 移除坐标轴并删除所有曲线
    m_chart->removeAxis(m_chart->axisX());
    m_chart->removeAxis(m_chart->axisY());
    m_chart->removeAllSeries(); // remove and delete all series
    m_series = nullptr;
    m_gridSeries = nullptr;
    m_chart->update(); // 用于清除删除曲线后的残留
}

void SquareWaveView::onIsDataPointShowChecked(bool isChecked)
{
    if(m_series!=nullptr){
        m_series->setPointLabelsVisible(isChecked);
    }
}

void SquareWaveView::onSetDataPointLabColorBtnClicked()
{
    if(m_series==nullptr){
        return ;
    }
    QColor seriesColor = m_series->pointLabelsColor();
    QColor color = QColorDialog::getColor(seriesColor);
    m_series->setPointLabelsColor(color);
}

void SquareWaveView::onSetDataPointLabFontBtnClicked()
{
    if(m_series==nullptr){
        return;
    }
    QFont seriesFont = m_series->pointLabelsFont();
    bool ok;
    QFont font = QFontDialog::getFont(&ok,seriesFont);
    if(ok){
        m_series->setPointLabelsFont(font);
    }
}

void SquareWaveView::onIsLegendVisibleChecked(bool isChecked)
{
    if(m_chart==nullptr){
        return;
    }
    QLegend* legend = m_chart->legend();
    legend->setVisible(isChecked);
}

void SquareWaveView::onxyPointBtnChecked()
{
    if(m_series==nullptr){
        return;
    }
    m_series->setPointLabelsFormat("(@xPoint,@yPoint)");
}

void SquareWaveView::onyPointBtnChecked()
{
    if(m_series==nullptr){
        return;
    }
    m_series->setPointLabelsFormat("@yPoint");
}

void SquareWaveView::onAxisBtnClicked()
{
    if(ui->xAxisBtn->isChecked()){
        m_axis = dynamic_cast<QValueAxis*>(m_chart->axisX(m_series));
    }else{
        m_axis = dynamic_cast<QValueAxis*>(m_chart->axisY(m_series));
    }
    initAxisTool();
}

void SquareWaveView::onSetAxisNameBtnClicked()
{
    if(m_axis==nullptr){
        return;
    }
    m_axis->setTitleText(ui->axisNameEdit->text());
}

void SquareWaveView::onSetTickColorBtnClicked()
{
    if(m_axis==nullptr){
        return;
    }
    QColor axisColor = m_axis->gridLineColor();
    QColor color = QColorDialog::getColor(axisColor);
    m_axis->setGridLineColor(color);
}

void SquareWaveView::onSetMinorTickColorBtnClicked()
{
    if(m_axis==nullptr){
        return;
    }
    QColor axisColor = m_axis->minorGridLineColor();
    QColor color = QColorDialog::getColor(axisColor);
    m_axis->setMinorGridLineColor(color);
}

void SquareWaveView::onAxisUpSpinBoxChanged(int value)
{
    if(m_axis==nullptr){
        return;
    }
    m_axis->setMax(value);
}

void SquareWaveView::onAxisDownSpinBoxChanged(int value)
{
    if(m_axis==nullptr){
        return;
    }
    m_axis->setMin(value);
}

void SquareWaveView::onSetTickSpinBoxChanged(int value)
{
    if(m_axis == nullptr){
        return;
    }
    m_axis->setTickCount(value);
}

void SquareWaveView::onSetMinorTickSpinBoxChanged(int value)
{
    if(m_axis == nullptr){
        return;
    }
    m_axis->setMinorTickCount(value);
}

void SquareWaveView::initAxisTool()
{
    if(m_axis == nullptr){
        return;
    }
    ui->isAxisNameVisible->setChecked(m_axis->isTitleVisible());
    ui->axisNameEdit->setText(m_axis->titleText());
    ui->axisUpSpinBox->setValue(m_axis->max());
    ui->axisDownSpinBox->setValue(m_axis->min());
    ui->setTickSpinBox->setValue(m_axis->tickCount());
    ui->setMinorTickSpinBox->setValue(m_axis->minorTickCount());
}
